package com.htcms.utils;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

/**
 * 用于Request的工具类
 * 
 * @author 朱锋 时间:2007-7-25
 */
public class RequestUtils {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger.getLogger(RequestUtils.class);

	/**
	 * 获取浏览器提交的整形参数
	 */
	public static int getParam(HttpServletRequest req, String param,
			int defaultValue) {
		String value = req.getParameter(param);
		if(StringUtils.isNotBlank(value)){
			int idx = value.indexOf('#');
			if (idx != -1)
				value = value.substring(0, idx);
			return Integer.parseInt(value);
		}else{
			return defaultValue;
		}

	}

	/**
	 * 获取浏览器提交的字符串参�?
	 */
	public static String getParam(HttpServletRequest req, String param,
			String defaultValue) {
		String value = req.getParameter(param);
		return (StringUtils.isEmpty(value)) ? defaultValue : value;
	}

	// ////////////////////////////////如果容器�?��,统一使用FILTER 进行过滤, 故把这个方法屏蔽
	// /**
	// * 获取浏览器提交的字符串参�?
	// */
	// public static String getParam(HttpServletRequest req, String param,
	// String defaultValue, String encoding) {
	// String value = req.getParameter(param);
	// if (StringUtils.isEmpty(value)) {
	// value = defaultValue;
	// } else {
	// try {
	//
	// value = new String(value.getBytes("ISO-8859-1"), encoding.toLowerCase());
	// //value=value;
	// } catch (Exception e) {
	// e.printStackTrace();
	// value = defaultValue;
	// }
	// }
	// return value;
	// }

	/**
	 * 设置COOKIE
	 * 
	 * @param name
	 * @param value
	 * @param maxAge
	 */
	public static void setCookie(HttpServletRequest request,
			HttpServletResponse response, String name, String value, int maxAge) {
		Cookie cookie = new Cookie(name, value);
		cookie.setMaxAge(maxAge);
		String serverName = request.getServerName();
		String domain = getDomainOfServerName(serverName);
		if (domain != null && domain.indexOf('.') != -1) {
			cookie.setDomain('.' + domain);
		}
		cookie.setPath("/");
		response.addCookie(cookie);
	}

	private final static List<String> domains = new ArrayList<String>() {
		{
			add("net");
			add("com");
			add("gov");
			add("edu");
			add("org");
		}
	};

	/**
	 * 获取用户访问URL中的根域�?例如: www.dlog.cn -> dlog.cn
	 * 
	 * @param req
	 * @return
	 */
	public static String getDomainOfServerName(String host) {
		if (StringUtils.isIPAddr(host))
			return null;
		String[] names = StringUtils.split(host, '.');
		int len = names.length;
		if (len >= 2) {
			if (domains.contains(names[len - 2]))
				return names[len - 3] + '.' + names[len - 2] + '.'
						+ names[len - 1];
			else
				return names[len - 2] + '.' + names[len - 1];
		}
		return host;
	}

	/**
	 * 获取COOKIE
	 * 
	 * @param name
	 */
	public static Cookie getCookie(HttpServletRequest request, String name) {
		Cookie[] cookies = request.getCookies();
		if (cookies == null)
			return null;
		for (int i = 0; i < cookies.length; i++) {
			if (name.equals(cookies[i].getName())) {
				return cookies[i];
			}
		}
		return null;
	}

	public static void setCookieByUTF8(HttpServletRequest request,
			HttpServletResponse response, String name, String value, int maxAge) {
		Cookie cookie = null;
		try {
			cookie = new Cookie(name, URLEncoder.encode(value, "UTF-8"));
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		cookie.setMaxAge(maxAge);
		String serverName = request.getServerName();
		String domain = getDomainOfServerName(serverName);
		if (domain != null && domain.indexOf('.') != -1) {
			cookie.setDomain('.' + domain);
		}
		cookie.setPath("/");
		response.addCookie(cookie);
	}

	/**
	 * 设置浏览器参数字符串
	 * 
	 * @param strBuf
	 * @param paramName
	 * @param paramValues
	 */
	public static void setQusetParamStr(StringBuffer strBuf, String paramName,
			Object... paramValues) {
		if (strBuf != null && paramValues != null && paramValues.length > 0) {
			for (Object paramValue : paramValues) {
				if (paramValue != null
						&& StringUtils.isNotBlank(paramValue.toString())) {
					if (strBuf.length() > 0) {
						strBuf.append("&");
					}
					strBuf.append(paramName);
					strBuf.append("=");
					strBuf.append(paramValue.toString());
				}
			}
		}
	}

	/**
	 * 将request的map 转码,并去掉前后空�?
	 * 
	 * @param requestMap
	 * @param encode_from
	 *            原来的编码，null的话默认ISO-8859-1
	 * @param encode_to
	 *            要转换后的编码，null的话默认GBK
	 * @param isUrlDecode
	 *            是否urldecode
	 * @return 转码后的map&lt;String,String[]&gt;
	 */
	@SuppressWarnings("unchecked")
	public static synchronized Map<String, String[]> handleEncoding(
			Map requestMap, String encode_from, String encode_to,
			boolean isUrlDecode) {
		if (encode_from == null || "".equals(encode_from)) {
			encode_from = "ISO-8859-1";
		}
		if (encode_to == null || "".equals(encode_to)) {
			encode_to = "GBK";
		}
		Map<String, String[]> encodeMap = new HashMap<String, String[]>();
		try {
			Set<String> key = requestMap.keySet();
			for (String paramKey : key) {
				String[] paramVals = (String[]) requestMap.get(paramKey);
				String[] encoded = new String[paramVals.length];
				if (isUrlDecode) {
					for (int i = 0; i < paramVals.length; i++) {

						String t = URLDecoder.decode(paramVals[i], encode_to);
						encoded[i] = new String(t.getBytes(encode_from),
								encode_to).trim();
					}
				} else {
					for (int i = 0; i < paramVals.length; i++) {
						encoded[i] = new String(paramVals[i]
								.getBytes(encode_from), encode_to).trim();
					}
				}
				encodeMap.put(paramKey, encoded);
			}
			// if (logger.isDebugEnabled()) {
			// logger.debug("页面参数转码");
			// printMapValues(encodeMap);
			// }
			return encodeMap;
		} catch (UnsupportedEncodingException e) {
			logger.error("页面参数转码问题错误:", e);
			e.printStackTrace();
		}

		return requestMap;
	}

	/**
	 * 取查询参数，将无值的参数去掉
	 * 
	 * @param pmap
	 * @return
	 */
	public static Map<String, String[]> getQueryString(
			Map<String, String[]> pmap) {
		Set<String> keyset = pmap.keySet();
		Map<String, String[]> query = new java.util.concurrent.ConcurrentHashMap<String, String[]>();

		for (Iterator<String> iterator = keyset.iterator(); iterator.hasNext();) {
			String key = iterator.next();
			String[] values = pmap.get(key);

			// 内容非空或非null
			// 只有�?���?
			if (values != null && values.length == 1) {
				if (StringUtils.isNotBlank(values[0])) {
					query.put(key, new String[] { values[0] });
				}
			} else {
				// 数组
				ArrayList<String> tmpList = new ArrayList<String>();
				for (int i = 0; i < values.length; i++) {
					if (StringUtils.isNotBlank(values[i])) {
						tmpList.add(values[i]);
					}
				}
				if (tmpList.size() != 0) {
					String[] tmp = new String[tmpList.size()];
					for (int i = 0; i < tmpList.size(); i++) {
						tmp[i] = tmpList.get(i);
					}

					query.put(key, tmp);
				}

			}

		}
		// if (logger.isDebugEnabled()) {
		// logger.debug("页面查询参数");
		// printMapValues(query);
		// }
		return query;
	}

	/**
	 * 设置浏览器参数字符串
	 * 
	 * @param querymap
	 *            参数map
	 * @param URLEncode
	 *            编码
	 * @return
	 */
	public static String setQueryString(Map<String, ?> querymap,
			String URLEncode) {
		StringBuffer result = new StringBuffer();
		Set<String> keyset = querymap.keySet();
		for (Iterator<String> iterator = keyset.iterator(); iterator.hasNext();) {
			String key = iterator.next();
			Object values = querymap.get(key);
			if (result.length() > 0) {
				result.append("&");
			}
			if (values instanceof String[]) {

				for (int i = 0; i < ((String[]) values).length; i++) {
					// result.append("?");
					result.append(key);
					result.append("=");

					if (URLEncode != null) {
						try {
							result.append(URLEncoder.encode(
									((String[]) values)[i], URLEncode));
						} catch (UnsupportedEncodingException e) {

							e.printStackTrace();
						}
					} else {
						result.append(((String[]) values)[i]);
					}
					if (i < ((String[]) values).length - 1) {
						result.append("&");
					}
				}
			} else if (values instanceof String) {
				result.append(key);
				result.append("=");
				if (URLEncode != null) {
					try {
						result.append(URLEncoder.encode((String) values,
								URLEncode));
					} catch (UnsupportedEncodingException e) {
						e.printStackTrace();
					}
				} else {
					result.append((String) values);
				}
			}
		}
		// if (logger.isDebugEnabled()) {
		// logger.debug("浏览器参数字符串:" + result.toString());
		// }
		return result.toString();
	}

	/**
	 * 自动将页面参数赋值至 bean
	 * 
	 * @param toBean
	 * @param request
	 * @return
	 */
	public static boolean copy(Object toBean, HttpServletRequest request) {
		boolean result = false;

		try {
			if (toBean != null && request != null) {
				Enumeration parNames = request.getParameterNames();
				String parTypeName;
				Class[] parTypes;

				Method[] bMethods = toBean.getClass().getMethods();

				while (parNames.hasMoreElements()) {
					String targetName = parNames.nextElement().toString();
					for (Method bMethod : bMethods) {

						if (bMethod.getName().toLowerCase().equals(
								"set" + targetName.toLowerCase())) {

							parTypes = bMethod.getParameterTypes();
							if (parTypes.length == 1) {// 判断参数是否只有�?��
								parTypeName = parTypes[0].getName();

								try {

									// 支持�?copy 类型
									if (parTypeName.equals(String.class
											.getName())
											|| parTypeName
													.equals(BigDecimal.class
															.getName())) {
										String param = RequestUtils.getParam(
												request, targetName, "");
										if (StringUtils.isBlank(param)) {
											String[] params = request
													.getParameterValues(targetName);
											if (params != null
													&& params.length == 1) {
												param = params[0];
											}
										}
										if (parTypeName.equals(BigDecimal.class
												.getName())) {
											bMethod.invoke(toBean,
													new BigDecimal(param));
										} else {
											bMethod.invoke(toBean, param);
										}

									} else if (parTypeName.equals(int.class
											.getName())
											|| parTypeName.equals(Integer.class
													.getName())) {
										String param = request
												.getParameter(targetName);
										int par = 0;
										if (StringUtils.isBlank(param)) {
											String[] params = request
													.getParameterValues(targetName);
											if (params != null
													&& params.length == 1
													&& StringUtils
															.isNotBlank(params[0])) {
												par = Integer
														.parseInt(params[0]);
											}
										} else {
											par = Integer.parseInt(param);
										}

										bMethod.invoke(toBean, par);
									}

								} catch (Exception e) {
									logger.error("",e);
								}
							}
						}
					}
				}
			}
		} catch (Exception e) {
			logger.error("",e);
		}
		return result;
	}

	/**
	 * 查看map的�?
	 * 
	 * @param map
	 * @return
	 */
	public static void printMapValues(Map<String, String[]> map) {
		StringBuffer result = new StringBuffer();
		Set<String> keys = map.keySet();
		for (String key : keys) {
			String[] vals = map.get(key);
			result.append("key:");
			result.append(key);
			result.append(" [ ");
			for (int i = 0; i < vals.length; i++) {
				String val = vals[i];
				result.append(val);
			}
			result.append(" ] ");

		}
		System.out.println(result.toString());
	}

}
